package org.mat.ipaas.ucenter.service.api.system;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.mat.framework.lang.dto.MatApiResponse;
import org.mat.ipaas.ucenter.service.dto.system.entity.SysUserAgentDTO;
import org.mat.ipaas.ucenter.service.dto.system.entity.SysUserDTO;
import org.mat.ipaas.ucenter.service.dto.system.entity.SysUserDepartDTO;
import org.mat.ipaas.ucenter.service.dto.system.entity.SysUserRoleDTO;
import org.mat.ipaas.ucenter.service.dto.system.model.DepartIdModelDTO;
import org.mat.ipaas.ucenter.service.dto.system.vo.SysDepartUsersVODTO;
import org.mat.ipaas.ucenter.service.dto.system.vo.SysUserRoleVODTO;
import org.mat.ipaas.ucenter.service.dto.system.vo.lowapp.DepartAndUserInfoDTO;
import org.mat.ipaas.ucenter.service.dto.system.vo.lowapp.UpdateDepartInfoDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @Author scott
 * @since 2018-12-20
 */
@FeignClient(name = "mat-ipaas-ucenter-service", contextId = "sys-user-rest-api")
public interface SysUserRestAPI {

    /**
     * 获取租户下用户数据（支持租户隔离）
     *
     * @param sysUserDTO
     * @param pageNo
     * @param pageSize
     * @return
     */
    @RequestMapping(value = "/sys/user/list", method = RequestMethod.GET)
    MatApiResponse<?> queryPageList(@SpringQueryMap SysUserDTO sysUserDTO,
                                    @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                    @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize);

    /**
     * 获取系统用户数据（查询全部用户，不做租户隔离）
     *
     * @param sysUserDTO
     * @param pageNo
     * @param pageSize
     * @return
     */
    //@RequiresPermissions("system:user:listAll")
    @RequestMapping(value = "/sys/user/listAll", method = RequestMethod.GET)
    MatApiResponse<?> queryAllPageList(@SpringQueryMap SysUserDTO sysUserDTO,
                                       @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                       @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize);

    //@RequiresPermissions("system:user:add")
    @RequestMapping(value = "/sys/user/add", method = RequestMethod.POST)
    MatApiResponse<SysUserDTO> add(@RequestBody JSONObject jsonObject);

    //@RequiresPermissions("system:user:edit")
    @RequestMapping(value = "/sys/user/edit", method = {RequestMethod.POST})
    MatApiResponse<SysUserDTO> edit(@RequestBody JSONObject jsonObject);

    /**
     * 删除用户
     */
    //@RequiresPermissions("system:user:delete")
    @RequestMapping(value = "/sys/user/delete", method = RequestMethod.DELETE)
    MatApiResponse<?> delete(@RequestParam(name = "id", required = true) String id);

    /**
     * 批量删除用户
     */
    //@RequiresPermissions("system:user:deleteBatch")
    @RequestMapping(value = "/sys/user/deleteBatch", method = RequestMethod.DELETE)
    MatApiResponse<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids);

    /**
     * 冻结&解冻用户
     *
     * @param jsonObject
     * @return
     */
    //@RequiresPermissions("system:user:frozenBatch")
    @RequestMapping(value = "/sys/user/frozenBatch", method = RequestMethod.PUT)
    MatApiResponse<SysUserDTO> frozenBatch(@RequestBody JSONObject jsonObject);

    //@RequiresPermissions("system:user:queryById")
    @RequestMapping(value = "/sys/user/queryById", method = RequestMethod.GET)
    MatApiResponse<SysUserDTO> queryById(@RequestParam(name = "id", required = true) String id);

    //@RequiresPermissions("system:user:queryUserRole")
    @RequestMapping(value = "/sys/user/queryUserRole", method = RequestMethod.GET)
    MatApiResponse<List<String>> queryUserRole(@RequestParam(name = "userid", required = true) String userid);


    /**
     * 校验用户账号是否唯一<br>
     * 可以校验其他 需要检验什么就传什么。。。
     *
     * @param sysUser
     * @return
     */
    @RequestMapping(value = "/sys/user/checkOnlyUser", method = RequestMethod.GET)
    MatApiResponse<Boolean> checkOnlyUser(SysUserDTO sysUser);

    /**
     * 修改密码
     */
    //@RequiresPermissions("system:user:changepwd")
    @RequestMapping(value = "/sys/user/changePassword", method = RequestMethod.PUT)
    MatApiResponse<?> changePassword(@RequestBody SysUserDTO sysUser);

    /**
     * 查询指定用户和部门关联的数据
     *
     * @param userId
     * @return
     */
    @RequestMapping(value = "/sys/user/userDepartList", method = RequestMethod.GET)
    MatApiResponse<List<DepartIdModelDTO>> getUserDepartsList(@RequestParam(name = "userId", required = true) String userId);

    /**
     * 生成在添加用户情况下没有主键的问题,返回给前端,根据该id绑定部门数据
     *
     * @return
     */
    @RequestMapping(value = "/sys/user/generateUserId", method = RequestMethod.GET)
    MatApiResponse<String> generateUserId();

    /**
     * 根据部门id查询用户信息
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/sys/user/queryUserByDepId", method = RequestMethod.GET)
    MatApiResponse<List<SysUserDTO>> queryUserByDepId(@RequestParam(name = "id", required = true) String id, @RequestParam(name = "realname", required = false) String realname);

    /**
     * 用户选择组件 专用  根据用户账号或部门分页查询
     *
     * @param departId
     * @param username
     * @return
     */
    @RequestMapping(value = "/sys/user/queryUserComponentData", method = RequestMethod.GET)
    MatApiResponse<IPage<SysUserDTO>> queryUserComponentData(
            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
            @RequestParam(name = "departId", required = false) String departId,
            @RequestParam(name = "realname", required = false) String realname,
            @RequestParam(name = "username", required = false) String username,
            @RequestParam(name = "id", required = false) String id);

    /**
     * 导出excel
     *
     * @param sysUser
     */
    //@RequiresPermissions("system:user:export")
    @RequestMapping(value = "/sys/user/exportXls")
    ModelAndView exportXls(SysUserDTO sysUser);

    /**
     * 通过excel导入数据
     *
     * @return
     */
    //@RequiresPermissions("system:user:import")
    @RequestMapping(value = "/sys/user/importExcel", method = RequestMethod.POST)
    MatApiResponse<?> importExcel() throws IOException;

    /**
     * @param userIds
     * @return
     * @功能：根据id 批量查询
     */
    @RequestMapping(value = "/sys/user/queryByIds", method = RequestMethod.GET)
    MatApiResponse<List<SysUserDTO>> queryByIds(@RequestParam String userIds);


    /**
     * @param userNames
     * @return
     * @功能：根据id 批量查询
     */
    @RequestMapping(value = "/sys/user/queryByNames", method = RequestMethod.GET)
    MatApiResponse<List<SysUserDTO>> queryByNames(@RequestParam String userNames);

    /**
     * 首页用户重置密码
     */
    //@RequiresPermissions("system:user:updatepwd")
    @RequestMapping(value = "/sys/user/updatePassword", method = RequestMethod.PUT)
    MatApiResponse<?> updatePassword(@RequestBody JSONObject json);

    @RequestMapping(value = "/sys/user/userRoleList", method = RequestMethod.GET)
    MatApiResponse<Page<SysUserDTO>> userRoleList(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                  @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize);

    /**
     * 给指定角色添加用户
     *
     * @param
     * @return
     */
    //@RequiresPermissions("system:user:addUserRole")
    @RequestMapping(value = "/sys/user/addSysUserRole", method = RequestMethod.POST)
    MatApiResponse<String> addSysUserRole(@RequestBody SysUserRoleVODTO sysUserRoleVODTO);

    /**
     * 删除指定角色的用户关系
     *
     * @param
     * @return
     */
    //@RequiresPermissions("system:user:deleteRole")
    @RequestMapping(value = "/sys/user/deleteUserRole", method = RequestMethod.DELETE)
    MatApiResponse<SysUserRoleDTO> deleteUserRole(@RequestParam(name = "roleId") String roleId,
                                                  @RequestParam(name = "userId", required = true) String userId
    );

    /**
     * 批量删除指定角色的用户关系
     *
     * @param
     * @return
     */
    //@RequiresPermissions("system:user:deleteRoleBatch")
    @RequestMapping(value = "/sys/user/deleteUserRoleBatch", method = RequestMethod.DELETE)
    MatApiResponse<SysUserRoleDTO> deleteUserRoleBatch(
            @RequestParam(name = "roleId") String roleId,
            @RequestParam(name = "userIds", required = true) String userIds);

    /**
     * 部门用户列表
     */
    @RequestMapping(value = "/sys/user/departUserList", method = RequestMethod.GET)
    MatApiResponse<Page<SysUserDTO>> departUserList(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                     @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize);


    /**
     * 根据 orgCode 查询用户，包括子部门下的用户
     * 若某个用户包含多个部门，则会显示多条记录，可自行处理成单条记录
     */
    @GetMapping("/sys/user/queryByOrgCode")
    MatApiResponse<?> queryByDepartId(
            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
            @RequestParam(name = "orgCode") String orgCode,
            @SpringQueryMap SysUserDTO sysUserDTO
    );

    /**
     * 根据 orgCode 查询用户，包括子部门下的用户
     * 针对通讯录模块做的接口，将多个部门的用户合并成一条记录，并转成对前端友好的格式
     */
    @GetMapping("/sys/user/queryByOrgCodeForAddressList")
    MatApiResponse<?> queryByOrgCodeForAddressList(
            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
            @RequestParam(name = "orgCode", required = false) String orgCode,
            @SpringQueryMap SysUserDTO sysUserDTO
    );

    /**
     * 给指定部门添加对应的用户
     */
    //@RequiresPermissions("system:user:editDepartWithUser")
    @RequestMapping(value = "/sys/user/editSysDepartWithUser", method = RequestMethod.POST)
    MatApiResponse<String> editSysDepartWithUser(@RequestBody SysDepartUsersVODTO sysDepartUsersVODTO);

    /**
     * 删除指定机构的用户关系
     */
    //@RequiresPermissions("system:user:deleteUserInDepart")
    @RequestMapping(value = "/sys/user/deleteUserInDepart", method = RequestMethod.DELETE)
    MatApiResponse<SysUserDepartDTO> deleteUserInDepart(@RequestParam(name = "depId") String depId,
                                                        @RequestParam(name = "userId", required = true) String userId
    );

    /**
     * 批量删除指定机构的用户关系
     */
    //@RequiresPermissions("system:user:deleteUserInDepartBatch")
    @RequestMapping(value = "/sys/user/deleteUserInDepartBatch", method = RequestMethod.DELETE)
    MatApiResponse<SysUserDepartDTO> deleteUserInDepartBatch(
            @RequestParam(name = "depId") String depId,
            @RequestParam(name = "userIds", required = true) String userIds);

    /**
     * 查询当前用户的所有部门/当前部门编码
     *
     * @return
     */
    @RequestMapping(value = "/sys/user/getCurrentUserDeparts", method = RequestMethod.GET)
    MatApiResponse<Map<String, Object>> getCurrentUserDeparts();

    /**
     * 用户注册接口
     *
     * @param jsonObject
     * @param sysUserDTO
     * @return
     */
    @PostMapping("/sys/user/register")
    MatApiResponse<JSONObject> userRegister(@RequestBody JSONObject jsonObject, @RequestParam("sysUserDTO") SysUserDTO sysUserDTO);

    /**
     * 用户手机号验证
     */
    @PostMapping("/sys/user/phoneVerification")
    MatApiResponse<Map<String, String>> phoneVerification(@RequestBody JSONObject jsonObject);

    /**
     * 用户更改密码
     */
    @GetMapping("/sys/user/passwordChange")
    MatApiResponse<SysUserDTO> passwordChange(@RequestParam(name = "username") String username,
                                              @RequestParam(name = "password") String password,
                                              @RequestParam(name = "smscode") String smscode,
                                              @RequestParam(name = "phone") String phone);


    /**
     * 根据TOKEN获取用户的部分信息（返回的数据是可供表单设计器使用的数据）
     *
     * @return
     */
    @GetMapping("/sys/user/getUserSectionInfoByToken")
    MatApiResponse<?> getUserSectionInfoByToken(@RequestHeader("X-Access-Token") String accessToken,
                                                @RequestParam(name = "token", required = false) String token);

    /**
     * 【APP端接口】获取用户列表  根据用户名和真实名 模糊匹配
     *
     * @param keyword
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("/sys/user/appUserList")
    MatApiResponse<?> appUserList(@RequestParam(name = "keyword", required = false) String keyword,
                                  @RequestParam(name = "username", required = false) String username,
                                  @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                  @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                  @RequestParam(name = "syncFlow", required = false) String syncFlow);

    /**
     * 获取被逻辑删除的用户列表，无分页
     *
     * @return logicDeletedUserList
     */
    @GetMapping("/sys/user/recycleBin")
    MatApiResponse getRecycleBin();

    /**
     * 还原被逻辑删除的用户
     *
     * @param jsonObject
     * @return
     */
    @RequestMapping(value = "/sys/user/putRecycleBin", method = RequestMethod.PUT)
    MatApiResponse putRecycleBin(@RequestHeader("X-Access-Token") String accessToken,
                                 @RequestBody JSONObject jsonObject);

    /**
     * 彻底删除用户
     *
     * @param userIds 被删除的用户ID，多个id用半角逗号分割
     * @return
     */
    //@RequiresPermissions("system:user:deleteRecycleBin")
    @RequestMapping(value = "/sys/user/deleteRecycleBin", method = RequestMethod.DELETE)
    MatApiResponse deleteRecycleBin(@RequestParam("userIds") String userIds);


    /**
     * 移动端修改用户信息
     *
     * @param jsonObject
     * @return
     */
    @RequestMapping(value = "/sys/user/appEdit", method = {RequestMethod.POST})
    MatApiResponse<SysUserDTO> appEdit(@RequestHeader("X-Access-Token") String accessToken,
                                       @RequestBody JSONObject jsonObject);

    /**
     * 移动端保存设备信息
     *
     * @param clientId
     * @return
     */
    @RequestMapping(value = "/sys/user/saveClientId", method = RequestMethod.GET)
    MatApiResponse<SysUserDTO> saveClientId(@RequestHeader("X-Access-Token") String accessToken,
                                            @RequestParam("clientId") String clientId);

    /**
     * 根据userid获取用户信息和部门员工信息
     *
     * @return Result
     */
    @GetMapping("/sys/user/queryChildrenByUsername")
    MatApiResponse queryChildrenByUsername(@RequestParam("userId") String userId);

    /**
     * 移动端查询部门用户信息
     *
     * @param departId
     * @return
     */
    @GetMapping("/sys/user/appQueryByDepartId")
    MatApiResponse<List<SysUserDTO>> appQueryByDepartId(@RequestParam(name = "departId", required = false) String departId);

    /**
     * 移动端查询用户信息(通过用户名模糊查询)
     *
     * @param keyword
     * @return
     */
    @GetMapping("/sys/user/appQueryUser")
    MatApiResponse<List<SysUserDTO>> appQueryUser(@RequestParam(name = "keyword", required = false) String keyword,
                                                  @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                  @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize);

    /**
     * 根据用户名修改手机号[该方法未使用]
     *
     * @param json
     * @return
     */
    @RequestMapping(value = "/sys/user/updateMobile", method = RequestMethod.PUT)
    MatApiResponse<?> changMobile(@RequestHeader("X-Access-Token") String accessToken,
                                  @RequestBody JSONObject json);


    /**
     * 根据对象里面的属性值作in查询 属性可能会变 用户组件用到
     *
     * @param sysUser
     * @return
     */
    @GetMapping("/sys/user/getMultiUser")
    List<SysUserDTO> getMultiUser(SysUserDTO sysUser);

    /**
     * 聊天 创建聊天组件专用  根据用户账号、用户姓名、部门id分页查询
     *
     * @param departId 部门id
     * @param keyword  搜索值
     * @return
     */
    @GetMapping(value = "/sys/user/getUserInformation")
    MatApiResponse<IPage<SysUserDTO>> getUserInformation(
            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
            @RequestParam(name = "departId", required = false) String departId,
            @RequestParam(name = "keyword", required = false) String keyword);

    /**
     * 简版流程用户选择组件
     *
     * @param departId 部门id
     * @param roleId   角色id
     * @param keyword  搜索值
     * @return
     */
    @GetMapping(value = "/sys/user/selectUserList")
    MatApiResponse<IPage<SysUserDTO>> selectUserList(
            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
            @RequestParam(name = "departId", required = false) String departId,
            @RequestParam(name = "roleId", required = false) String roleId,
            @RequestParam(name = "keyword", required = false) String keyword);

    /**
     * 用户离职(新增代理人和用户状态变更操作)【低代码应用专用接口】
     *
     * @param sysUserAgentDTO
     * @return
     */
    @PutMapping("/sys/user/userQuitAgent")
    MatApiResponse<String> userQuitAgent(@RequestBody SysUserAgentDTO sysUserAgentDTO);

    /**
     * 获取被逻辑删除的用户列表，无分页【低代码应用专用接口】
     *
     * @return List<SysUserDTO>
     */
    @GetMapping("/sys/user/getQuitList")
    MatApiResponse<List<SysUserDTO>> getQuitList(@RequestParam HttpServletRequest req);

    /**
     * 更新刪除状态和离职状态【低代码应用专用接口】
     *
     * @param jsonObject
     * @return Result<String>
     */
    @PutMapping("/sys/user/putCancelQuit")
    MatApiResponse<String> putCancelQuit(@RequestBody JSONObject jsonObject, @RequestParam HttpServletRequest request);

    /**
     * 获取用户信息(vue3用户设置专用)【低代码应用专用接口】
     *
     * @return
     */
    @GetMapping("/sys/user/login/setting/getUserData")
    MatApiResponse<SysUserDTO> getUserData(@RequestHeader("X-Access-Token") String accessToken);

    /**
     * 用户编辑(vue3用户设置专用)【低代码应用专用接口】
     *
     * @param sysUser
     * @return
     */
    @PostMapping("/sys/user/login/setting/userEdit")
    //@RequiresPermissions("system:user:setting:edit")
    MatApiResponse<String> userEdit(@RequestHeader("X-Access-Token") String accessToken,
                                    @RequestBody SysUserDTO sysUser);

    /**
     * 批量修改 【low-app】
     *
     * @param jsonObject
     * @return
     */
    @PutMapping("/sys/user/batchEditUsers")
    MatApiResponse<SysUserDTO> batchEditUsers(@RequestBody JSONObject jsonObject);

    /**
     * 根据关键词搜索部门和用户【low-app】
     *
     * @param keyword
     * @return
     */
    @GetMapping("/sys/user/searchByKeyword")
    MatApiResponse<DepartAndUserInfoDTO> searchByKeyword(@RequestParam(name = "keyword", required = false) String keyword);

    /**
     * 编辑部门前获取部门相关信息 【low-app】
     *
     * @param id
     * @return
     */
    @GetMapping("/sys/user/getUpdateDepartInfo")
    MatApiResponse<UpdateDepartInfoDTO> getUpdateDepartInfo(@RequestParam(name = "id", required = false) String id);

    /**
     * 编辑部门 【low-app】
     *
     * @param updateDepartInfoDTO
     * @return
     */
    @PutMapping("/sys/user/doUpdateDepartInfo")
    MatApiResponse<?> doUpdateDepartInfo(@RequestBody UpdateDepartInfoDTO updateDepartInfoDTO);

    /**
     * 设置负责人 取消负责人
     *
     * @param json
     * @return
     */
    @PutMapping("/sys/user/changeDepartChargePerson")
    MatApiResponse<?> changeDepartChargePerson(@RequestBody JSONObject json);

    /**
     * 修改租户下的用户【低代码应用专用接口】
     *
     * @param sysUser
     * @return
     */
    @RequestMapping(value = "/sys/user/editTenantUser", method = {RequestMethod.POST})
    MatApiResponse<String> editTenantUser(@RequestBody SysUserDTO sysUser);
}
